package repository

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/service/user/model"

	"github.com/sirupsen/logrus"
	"github.com/volatiletech/null/v8"
	"github.com/volatiletech/sqlboiler/v4/boil"
	"github.com/volatiletech/sqlboiler/v4/queries"
	"github.com/volatiletech/sqlboiler/v4/queries/qm"
	"github.com/zeromicro/go-zero/core/stores/cache"
)

type (
	// CurrentUserRepository is an interface to be customized, add more methods here,
	// and implement the added methods in customCurrentUserRepository.
	CurrentUserRepository interface {
		FindOne(ctx context.Context, id uint64) (*model.User, error)
		FindOneWithExpire(
			ctx context.Context,
			id uint64,
			expire time.Duration,
		) (*model.User, error)
		FindOneNoCache(
			ctx context.Context,
			conn boil.ContextExecutor,
			id uint64,
		) (*model.User, error)
		GetList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.User, int64, error) // ##24.11.06##
		Insert(
			ctx context.Context,
			tx boil.ContextExecutor,
			data *model.User,
			rel *model.UserRel,
		) error // #24.03.29#
		Update(
			ctx context.Context,
			tx boil.ContextExecutor,
			data *model.User,
			rel *model.UserRel,
		) error
		UpdateBatch(ctx context.Context, tx boil.ContextExecutor, ids []uint64, cols model.M) error
		SoftDelete(ctx context.Context, tx boil.ContextExecutor, id uint64) error
		Restore(ctx context.Context, tx boil.ContextExecutor, id uint64) error
		ForceDelete(ctx context.Context, tx boil.ContextExecutor, id uint64) error
		ForceDeleteBatch(ctx context.Context, tx boil.ContextExecutor, ids []uint64) error

		SyncQiniu(ctx context.Context, id uint64, mediaId uint64, url string) (int64, error) // ##25.02.18##

		GetAuthList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserAuth, int64, error) // ##24.10.25##
		GetDetailList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserDetail, int64, error) // ##24.10.25##
		GetAccountList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserAccount, int64, error) // ##24.10.25##
		GetMeta(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserMetum, int64, error) // #24.03.29#
		GetMedia(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserAttachmentRelationship, int64, error)
		UpdateAccountBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			cols model.M,
			filter map[string]map[string][]any,
		) (int64, error)
		IncreaseBalanceBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			userIds []uint64,
			step int,
		) error
		IncreaseIntegralBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			userIds []uint64,
			step int,
		) error
		IncreaseGrowthBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			userIds []uint64,
			step int,
		) error
		UpdateMetum(
			ctx context.Context,
			tx boil.ContextExecutor,
			userMetum *model.UserMetum,
		) error // ##25.03.12##
		UpdateMeta(
			ctx context.Context,
			tx boil.ContextExecutor,
			meta []*model.UserMetum,
			delMetaIds []uint64,
		) error
		IncreaseMeta(
			ctx context.Context,
			tx boil.ContextExecutor,
			userId uint64,
			metaKey string,
			step int,
		) error // ##25.03.12##
		InsertTransactionLog(
			ctx context.Context,
			tx boil.ContextExecutor,
			log *model.UserTransactionLog,
		) error
		GetTransactionLogList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserTransactionLog, int64, error)
		UpdateTransactionLogBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			cols model.M,
			filter map[string]map[string][]any,
		) (int64, error)
		InsertTaskLog(
			ctx context.Context,
			tx boil.ContextExecutor,
			log *model.UserTaskLog,
		) error
		InsertIntegralTransactionLog(
			ctx context.Context,
			tx boil.ContextExecutor,
			log *model.UserIntegralTransactionLog,
		) error
		GetIntegralTransactionLog(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserIntegralTransactionLog, int64, error) // ##25.05.14##
		GetTaskLogList(
			ctx context.Context,
			cols model.M,
			withCount int,
			filter map[string]map[string][]any,
		) ([]*model.UserTaskLog, int64, error)
		UpdateTaskLogBatch(
			ctx context.Context,
			tx boil.ContextExecutor,
			cols model.M,
			filter map[string]map[string][]any,
		) (int64, error)
		UpdateIntegralTransactionLog(
			ctx context.Context,
			tx boil.ContextExecutor,
			data *model.UserIntegralTransactionLog,
		) error
		FindOneNoCacheIntegralTransactionLog(
			ctx context.Context,
			conn boil.ContextExecutor,
			id uint64,
		) (*model.UserIntegralTransactionLog, error)
	}

	customCurrentUserRepository struct {
		modelx.CachedConn
		mysqlConn           *sql.DB
		cacheIdPrefix       string
		cacheIdExpirePrefix string
	}

	// Custom struct for selecting a subset of data
	RandomInfo struct {
		MaxId int     `boil:"max_id"`
		MinId int     `boil:"min_id"`
		Rand  float64 `boil:"rand"`
	}
)

// NewCurrentUserRepository returns a repository for the database table.
func NewCurrentUserRepository(mysqlConn *sql.DB, cacheConf cache.CacheConf) CurrentUserRepository {
	return &customCurrentUserRepository{
		CachedConn:          modelx.NewConn(mysqlConn, cacheConf),
		mysqlConn:           mysqlConn,
		cacheIdPrefix:       "cache:user:users:id:",
		cacheIdExpirePrefix: "cache:user:users:id:expire:",
	}
}

func (r *customCurrentUserRepository) FindOne(
	ctx context.Context,
	id uint64,
) (*model.User, error) { // #24.07.09#
	cacheIdKey := r.formatPrimary(id)
	var resp model.User
	err := r.QueryCtx(ctx, &resp, cacheIdKey, func(ctx context.Context, conn *sql.DB, v any) error {
		data, err := model.FindUser(ctx, conn, id)
		if err != nil {
			return err
		}

		*v.(*model.User) = *data

		return nil
	})

	switch err {
	case nil:
		return &resp, nil
	case sql.ErrNoRows:
		return nil, model.ErrNotFound
	default:
		return nil, err
	}
}

func (r *customCurrentUserRepository) FindOneWithExpire(
	ctx context.Context,
	id uint64,
	expire time.Duration,
) (*model.User, error) {
	cacheIdKey := r.formatPrimaryWithExpire(id)
	var resp model.User
	err := r.QueryWithExpireCtx(ctx, &resp, cacheIdKey, expire, func(ctx context.Context, conn *sql.DB, v any) error {
		data, err := model.FindUser(ctx, conn, id)
		if err != nil {
			return err
		}

		*v.(*model.User) = *data

		return nil
	})

	switch err {
	case nil:
		return &resp, nil
	case sql.ErrNoRows:
		return nil, model.ErrNotFound
	default:
		return nil, err
	}
}

func (r *customCurrentUserRepository) FindOneNoCache(
	ctx context.Context,
	conn boil.ContextExecutor,
	id uint64,
) (*model.User, error) {
	var db boil.ContextExecutor = r.mysqlConn
	if conn != nil {
		db = conn
	}
	data, err := model.FindUser(ctx, db, id)
	switch err {
	case nil:
		return data, nil
	case sql.ErrNoRows:
		return nil, model.ErrNotFound
	default:
		return nil, err
	}
}

// withCount
// -1-返回list；0-返回count；1-返回count和list；2-根据offset返回count和list；
// 3-根据preMinId返回count和list；4-根据preMaxId返回count和list；5-统计参与次数、统计领取次数
func (r *customCurrentUserRepository) GetList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.User, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserColumns.ID+" DESC"))
					mods = append(mods, model.UserWhere.ID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserColumns.ID+" ASC"))
					mods = append(mods, model.UserWhere.ID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserColumns.ID:
				mods = append(mods, modelx.GetIntMods(model.UserColumns.ID, opMap)...)
			case model.UserColumns.UserLogin:
				mods = append(mods, modelx.GetStringMods(model.UserColumns.UserLogin, opMap)...)
			case model.UserColumns.UserEmail:
				mods = append(mods, modelx.GetStringMods(model.UserColumns.UserEmail, opMap)...)
			case model.UserColumns.UserMobile:
				mods = append(mods, modelx.GetStringMods(model.UserColumns.UserMobile, opMap)...)
			case model.UserColumns.UserStatus:
				mods = append(mods, modelx.GetIntMods(model.UserColumns.UserStatus, opMap)...)
			case model.UserColumns.UserEmailVerified:
				mods = append(mods, modelx.GetIntMods(model.UserColumns.UserEmailVerified, opMap)...)
			case model.UserColumns.UserEmailVerifiedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserColumns.UserEmailVerifiedAt, opMap)...)
			case model.UserColumns.UserMobileVerified:
				mods = append(mods, modelx.GetIntMods(model.UserColumns.UserMobileVerified, opMap)...)
			case model.UserColumns.UserMobileVerifiedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserColumns.UserMobileVerifiedAt, opMap)...)
			case model.UserColumns.CreatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserColumns.CreatedAt, opMap)...)
			case model.UserColumns.UpdatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserColumns.UpdatedAt, opMap)...)
			case model.UserColumns.DeletedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserColumns.DeletedAt, opMap)...)
			case model.UserColumns.IsSystem:
				mods = append(mods, modelx.GetBooleanMods(model.UserColumns.IsSystem, opMap)...)
			case model.UserColumns.CreateIP:
				mods = append(mods, modelx.GetStringMods(model.UserColumns.CreateIP, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.Users(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserColumns.ID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.Users(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) Insert(
	ctx context.Context,
	tx boil.ContextExecutor,
	data *model.User,
	rel *model.UserRel,
) error {
	err := r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		err := data.Insert(ctx, db, boil.Infer())
		if err != nil {
			return err
		}

		uid := data.ID
		now := time.Now()
		account := &model.UserAccount{
			UserID:    uid,
			RankID:    uint16(globalkey.DefaultMemberRankId),
			CreatedAt: now,
			UpdatedAt: now,
		}
		err = account.Insert(ctx, db, boil.Infer())
		if err != nil {
			return err
		}

		if rel == nil {
			return nil
		}

		if rel.Auth != nil {
			rel.Auth.UserID = uid
			err = rel.Auth.Insert(ctx, db, boil.Infer())
			if err != nil {
				return err
			}
		}

		if rel.Detail != nil {
			rel.Detail.UserID = uid
			err = rel.Detail.Insert(ctx, db, boil.Infer())
			if err != nil {
				return err
			}
		}

		if len(rel.Meta) > 0 {
			for _, v := range rel.Meta {
				v.UserID = uid
				err = v.Insert(ctx, db, boil.Infer())
				if err != nil {
					return err
				}
			}
		}

		if len(rel.Media) > 0 {
			for _, v := range rel.Media {
				v.UserID = uid
				err = v.Insert(ctx, db, boil.Infer())
				if err != nil {
					return err
				}
			}
		}

		return nil
	}, r.getCacheKeys(data)...)

	return err
}

func (r *customCurrentUserRepository) Update(
	ctx context.Context,
	tx boil.ContextExecutor,
	data *model.User,
	rel *model.UserRel,
) error {
	err := r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		var uid uint64

		if data != nil {
			rowsAff, err := data.Update(ctx, db, boil.Blacklist(
				model.UserColumns.ID,
				model.UserColumns.DeletedAt,
			))
			if err != nil {
				return err
			}

			if rowsAff == 0 {
				return model.ErrNotUpdated
			}

			uid = data.ID
		}

		if rel == nil {
			return nil
		}

		if uid == 0 {
			if rel.Auth != nil {
				uid = rel.Auth.UserID
			} else if rel.Detail != nil {
				uid = rel.Detail.UserID
			} else {
				return nil
			}
		}

		if rel.Auth != nil && rel.Auth.UserID == uid {
			if rel.Auth.UserAuthID > 0 {
				_, err := rel.Auth.Update(ctx, db, boil.Blacklist(
					model.UserAuthColumns.UserAuthID,
					model.UserAuthColumns.UserID,
					model.UserAuthColumns.PlatformID,
					model.UserAuthColumns.UserSource,
				))
				if err != nil {
					return err
				}
			} else {
				err := rel.Auth.Insert(ctx, db, boil.Infer())
				if err != nil {
					return err
				}
			}
		}

		if rel.Detail != nil && rel.Detail.UserID == uid {
			if rel.Detail.UserDetailID > 0 {
				_, err := rel.Detail.Update(ctx, db, boil.Blacklist(
					model.UserDetailColumns.UserDetailID,
					model.UserDetailColumns.UserID,
				))
				if err != nil {
					return err
				}
			} else {
				err := rel.Detail.Insert(ctx, db, boil.Infer())
				if err != nil {
					return err
				}
			}
		}

		if len(rel.Meta) > 0 {
			for _, v := range rel.Meta {
				if v.MetaID > 0 {
					_, err := v.Update(ctx, db, boil.Blacklist(
						model.UserMetumColumns.MetaID,
						model.UserMetumColumns.UserID,
						model.UserMetumColumns.MetaKey,
					))
					if err != nil {
						return err
					}
				} else {
					v.UserID = uid
					err := v.Insert(ctx, db, boil.Infer())
					if err != nil {
						return err
					}
				}
			}
		}
		if len(rel.DelMetaIds) > 0 {
			var mods []qm.QueryMod
			mods = append(mods, model.UserMetumWhere.MetaID.IN(rel.DelMetaIds))
			_, err := model.UserMeta(mods...).DeleteAll(ctx, db)
			if err != nil {
				return err
			}
		}

		if len(rel.Media) > 0 {
			for _, v := range rel.Media {
				if v.AttachmentRelationshipID > 0 {
					_, err := v.Update(ctx, db, boil.Blacklist(
						model.UserAttachmentRelationshipColumns.AttachmentRelationshipID,
						model.UserAttachmentRelationshipColumns.UserID,
					))
					if err != nil {
						return err
					}
				} else {
					v.UserID = uid
					err := v.Insert(ctx, db, boil.Infer())
					if err != nil {
						return err
					}
				}
			}
		}

		if len(rel.DelMediaIds) > 0 {
			var mods []qm.QueryMod
			mods = append(mods, model.UserAttachmentRelationshipWhere.AttachmentRelationshipID.IN(rel.DelMediaIds))
			_, err := model.UserAttachmentRelationships(mods...).DeleteAll(ctx, db)
			if err != nil {
				return err
			}
		}

		return nil
	}, r.getCacheKeys(data)...)

	return err
}

func (r *customCurrentUserRepository) UpdateBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	ids []uint64,
	cols model.M,
) error {
	if len(ids) > 0 {
		err := r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
			var db boil.ContextExecutor
			if tx != nil {
				db = tx
			} else {
				db = conn
			}

			var mods []qm.QueryMod
			mods = append(mods, model.UserWhere.ID.IN(ids))
			rowsAff, err := model.Users(mods...).UpdateAll(ctx, db, cols)
			if err != nil {
				return err
			}

			if rowsAff == 0 {
				return model.ErrNotUpdated
			}

			return nil
		}, r.formatPrimaries(ids)...)

		return err
	}

	return nil
}

func (r *customCurrentUserRepository) SoftDelete(
	ctx context.Context,
	tx boil.ContextExecutor,
	id uint64,
) error {
	data, err := r.FindOneNoCache(ctx, tx, id)
	if err != nil {
		if err == model.ErrNotFound {
			return nil
		}

		return err
	}

	if data.UserStatus == uint16(globalkey.StatusDeleted) {
		return nil
	}

	data.DelStatus = data.UserStatus
	data.UserStatus = uint16(globalkey.StatusDeleted)
	data.DeletedAt = null.TimeFrom(time.Now())

	err = r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		rowsAff, err := data.Update(ctx, db, boil.Blacklist(
			model.UserColumns.ID,
			model.UserColumns.UpdatedAt,
		))
		if err != nil {
			return err
		}

		if rowsAff == 0 {
			return model.ErrNotUpdated
		}

		return nil
	}, r.getCacheKeys(data)...)

	return err
}

func (r *customCurrentUserRepository) Restore(
	ctx context.Context,
	tx boil.ContextExecutor,
	id uint64,
) error {
	data, err := r.FindOneNoCache(ctx, tx, id)
	if err != nil {
		if err == model.ErrNotFound {
			return nil
		}

		return err
	}

	if data.UserStatus != uint16(globalkey.StatusDeleted) {
		return nil
	}

	data.UserStatus = data.DelStatus
	data.DeletedAt = null.TimeFromPtr(nil)

	err = r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		rowsAff, err := data.Update(ctx, db, boil.Blacklist(
			model.UserColumns.ID,
			model.UserColumns.UpdatedAt,
		))
		if err != nil {
			return err
		}

		if rowsAff == 0 {
			return model.ErrNotUpdated
		}

		return nil
	}, r.getCacheKeys(data)...)

	return err
}

func (r *customCurrentUserRepository) ForceDelete(
	ctx context.Context,
	tx boil.ContextExecutor,
	id uint64,
) error {
	data, err := r.FindOneNoCache(ctx, tx, id)
	if err != nil {
		if err == model.ErrNotFound {
			return nil
		}

		return err
	}

	err = r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		rowsAff, err := data.Delete(ctx, db)
		if err != nil {
			return err
		}

		if rowsAff == 0 {
			return model.ErrNotDeleted
		}

		return nil
	}, r.getCacheKeys(data)...)

	return err
}

func (r *customCurrentUserRepository) ForceDeleteBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	ids []uint64,
) error {
	if len(ids) > 0 {
		err := r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
			var db boil.ContextExecutor
			if tx != nil {
				db = tx
			} else {
				db = conn
			}

			var mods []qm.QueryMod
			mods = append(mods, model.UserWhere.ID.IN(ids))

			rowsAff, err := model.Users(mods...).DeleteAll(ctx, db)
			if err != nil {
				return err
			}

			if rowsAff == 0 {
				return model.ErrNotDeleted
			}

			return nil
		}, r.formatPrimaries(ids)...)

		return err
	}

	return nil
}

func (r *customCurrentUserRepository) SyncQiniu(ctx context.Context, id uint64, mediaId uint64, url string) (rowsAff int64, err error) {
	var mods []qm.QueryMod
	mods = append(mods, model.UserAttachmentRelationshipWhere.UserID.EQ(id))
	mods = append(mods, model.UserAttachmentRelationshipWhere.AttachmentID.EQ(mediaId))
	// list, err := model.UserAttachmentRelationships(mods...).All(ctx, r.mysqlConn)
	// if err != nil {
	// 	return
	// }

	// if len(list) == 0 {
	// 	return
	// }

	rowsAff, err = model.UserAttachmentRelationships(mods...).UpdateAll(ctx, r.mysqlConn, model.M{
		model.UserAttachmentRelationshipColumns.AttachmentImageURL: url,
	})

	return
}

func (r *customCurrentUserRepository) getCacheKeys(data *model.User) []string {
	if data == nil {
		return []string{}
	}

	cacheIdKey := r.formatPrimary(data.ID)
	cacheIdExpireKey := r.formatPrimaryWithExpire(data.ID)
	cacheKeys := []string{
		cacheIdKey,
		cacheIdExpireKey,
	}

	return cacheKeys
}

func (r *customCurrentUserRepository) formatPrimary(primary any) string {
	return fmt.Sprintf("%s%v", r.cacheIdPrefix, primary)
}

func (r *customCurrentUserRepository) formatPrimaryWithExpire(primary any) string {
	return fmt.Sprintf("%s%v", r.cacheIdExpirePrefix, primary)
}

func (r *customCurrentUserRepository) formatPrimaries(primaries []uint64) []string {
	var resp []string
	for _, primary := range primaries {
		resp = append(resp, r.formatPrimary(primary))
		resp = append(resp, r.formatPrimaryWithExpire(primary))
	}

	return resp
}

func (r *customCurrentUserRepository) queryPrimary(ctx context.Context, conn *sql.DB, v any, primary any) error {
	var uid uint64
	if jsonId, ok := primary.(json.Number); ok {
		if int64Id, err := jsonId.Int64(); err == nil {
			uid = uint64(int64Id)
		} else {
			return err
		}
	}

	data, err := model.FindUser(ctx, conn, uid)
	if err != nil {
		return err
	}

	*v.(*model.User) = *data

	return nil
}

func (r *customCurrentUserRepository) GetAuthList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserAuth, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAuthColumns.UserAuthID+" DESC"))
					mods = append(mods, model.UserAuthWhere.UserAuthID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAuthColumns.UserAuthID+" ASC"))
					mods = append(mods, model.UserAuthWhere.UserAuthID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserAuthColumns.UserAuthID:
				mods = append(mods, modelx.GetIntMods(model.UserAuthColumns.UserAuthID, opMap)...)
			case model.UserAuthColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserAuthColumns.UserID, opMap)...)
			case model.UserAuthColumns.PlatformID:
				mods = append(mods, modelx.GetIntMods(model.UserAuthColumns.PlatformID, opMap)...)
			case model.UserAuthColumns.Openid:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Openid, opMap)...)
			case model.UserAuthColumns.Unionid:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Unionid, opMap)...)
			case model.UserAuthColumns.Nickname:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Nickname, opMap)...)
			case model.UserAuthColumns.Gender:
				mods = append(mods, modelx.GetIntMods(model.UserAuthColumns.Gender, opMap)...)
			case model.UserAuthColumns.Country:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Country, opMap)...)
			case model.UserAuthColumns.Province:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Province, opMap)...)
			case model.UserAuthColumns.City:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.City, opMap)...)
			case model.UserAuthColumns.Language:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Language, opMap)...)
			case model.UserAuthColumns.Status:
				mods = append(mods, modelx.GetIntMods(model.UserAuthColumns.Status, opMap)...)
			case model.UserAuthColumns.CreatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserAuthColumns.CreatedAt, opMap)...)
			case model.UserAuthColumns.UpdatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserAuthColumns.UpdatedAt, opMap)...)
			case model.UserAuthColumns.Mobile:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.Mobile, opMap)...)
			case model.UserAuthColumns.Birthday:
				mods = append(mods, modelx.GetTimeMods(model.UserAuthColumns.Birthday, opMap)...)
			case model.UserAuthColumns.UserSource:
				mods = append(mods, modelx.GetStringMods(model.UserAuthColumns.UserSource, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserAuths(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserAuthColumns.UserAuthID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserAuths(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) GetDetailList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserDetail, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserDetailColumns.UserDetailID+" DESC"))
					mods = append(mods, model.UserDetailWhere.UserDetailID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserDetailColumns.UserDetailID+" ASC"))
					mods = append(mods, model.UserDetailWhere.UserDetailID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserDetailColumns.UserDetailID:
				mods = append(mods, modelx.GetIntMods(model.UserDetailColumns.UserDetailID, opMap)...)
			case model.UserDetailColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserDetailColumns.UserID, opMap)...)
			case model.UserDetailColumns.Nickname:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.Nickname, opMap)...)
			case model.UserDetailColumns.UserNicename:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.UserNicename, opMap)...)
			case model.UserDetailColumns.DisplayName:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.DisplayName, opMap)...)
			case model.UserDetailColumns.Gender:
				mods = append(mods, modelx.GetIntMods(model.UserDetailColumns.Gender, opMap)...)
			case model.UserDetailColumns.Birthday:
				mods = append(mods, modelx.GetTimeMods(model.UserDetailColumns.Birthday, opMap)...)
			case model.UserDetailColumns.Country:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.Country, opMap)...)
			case model.UserDetailColumns.Province:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.Province, opMap)...)
			case model.UserDetailColumns.City:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.City, opMap)...)
			case model.UserDetailColumns.Language:
				mods = append(mods, modelx.GetStringMods(model.UserDetailColumns.Language, opMap)...)
			case model.UserDetailColumns.Role:
				mods = append(mods, modelx.GetIntMods(model.UserDetailColumns.Role, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserDetails(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserDetailColumns.UserDetailID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserDetails(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) GetAccountList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserAccount, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAccountColumns.UserAccountID+" DESC"))
					mods = append(mods, model.UserAccountWhere.UserAccountID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAccountColumns.UserAccountID+" ASC"))
					mods = append(mods, model.UserAccountWhere.UserAccountID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserAccountColumns.UserAccountID:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.UserAccountID, opMap)...)
			case model.UserAccountColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.UserID, opMap)...)
			case model.UserAccountColumns.Point:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.Point, opMap)...)
			case model.UserAccountColumns.FrozenPoint:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.FrozenPoint, opMap)...)
			case model.UserAccountColumns.HistoryPoint:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.HistoryPoint, opMap)...)
			case model.UserAccountColumns.Balance:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.Balance, opMap)...)
			case model.UserAccountColumns.FrozenBalance:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.FrozenBalance, opMap)...)
			case model.UserAccountColumns.RankID:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.RankID, opMap)...)
			case model.UserAccountColumns.Loan:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.Loan, opMap)...)
			case model.UserAccountColumns.Credit:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.Credit, opMap)...)
			case model.UserAccountColumns.Level:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.Level, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserAccounts(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserAccountColumns.UserAccountID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserAccounts(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) GetMeta(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserMetum, count int64, err error) { // #24.07.09#
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserMetumColumns.MetaID+" DESC"))
					mods = append(mods, model.UserMetumWhere.MetaID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserMetumColumns.MetaID+" ASC"))
					mods = append(mods, model.UserMetumWhere.MetaID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserMetumColumns.MetaID:
				mods = append(mods, modelx.GetIntMods(model.UserMetumColumns.MetaID, opMap)...)
			case model.UserMetumColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserMetumColumns.UserID, opMap)...)
			case model.UserMetumColumns.MetaKey:
				mods = append(mods, modelx.GetStringMods(model.UserMetumColumns.MetaKey, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserMeta(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserMetumColumns.MetaID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserMeta(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) GetMedia(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserAttachmentRelationship, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAttachmentRelationshipColumns.AttachmentRelationshipID+" DESC"))
					mods = append(mods, model.UserAttachmentRelationshipWhere.AttachmentRelationshipID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserAttachmentRelationshipColumns.AttachmentRelationshipID+" ASC"))
					mods = append(mods, model.UserAttachmentRelationshipWhere.AttachmentRelationshipID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserAttachmentRelationshipColumns.AttachmentRelationshipID:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.AttachmentRelationshipID, opMap)...)
			case model.UserAttachmentRelationshipColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.UserID, opMap)...)
			case model.UserAttachmentRelationshipColumns.Type:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.Type, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentID:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.AttachmentID, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentThumbnail:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.AttachmentThumbnail, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentOrder:
				mods = append(mods, modelx.GetIntMods(model.UserAttachmentRelationshipColumns.AttachmentOrder, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentSource:
				mods = append(mods, modelx.GetStringMods(model.UserAttachmentRelationshipColumns.AttachmentSource, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentImageURL:
				mods = append(mods, modelx.GetStringMods(model.UserAttachmentRelationshipColumns.AttachmentImageURL, opMap)...)
			case model.UserAttachmentRelationshipColumns.AttachmentImageAlt:
				mods = append(mods, modelx.GetStringMods(model.UserAttachmentRelationshipColumns.AttachmentImageAlt, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserAttachmentRelationships(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserAttachmentRelationshipColumns.AttachmentRelationshipID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserAttachmentRelationships(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) UpdateAccountBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	cols model.M,
	filter map[string]map[string][]any,
) (rowsAff int64, err error) {
	var mods []qm.QueryMod
	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserAccountColumns.UserAccountID:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.UserAccountID, opMap)...)
			case model.UserAccountColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserAccountColumns.UserID, opMap)...)
			}
		}
	}

	if len(mods) == 0 {
		return
	}

	var db boil.ContextExecutor
	if tx != nil {
		db = tx
	} else {
		db = r.mysqlConn
	}

	return model.UserAccounts(mods...).UpdateAll(ctx, db, cols)
}

func (r *customCurrentUserRepository) IncreaseBalanceBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	userIds []uint64,
	step int,
) error {
	var uids []string
	if len(userIds) > 0 {
		for _, uid := range userIds {
			if uid > 0 {
				uids = append(uids, strconv.FormatInt(int64(uid), 10))
			}
		}
	}

	if len(uids) > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		res, err := queries.Raw(fmt.Sprintf(
			`update %s set %s=%s+%d where %s in (%s)`,
			model.TableNames.UserAccount,
			model.UserAccountColumns.Balance,
			model.UserAccountColumns.Balance,
			step,
			model.UserAccountColumns.UserID,
			strings.Join(uids, ","),
		)).Exec(db)

		logrus.Info(fmt.Sprintf("IncreaseBalanceBatch res: %+v", res))
		logrus.Info(fmt.Sprintf("IncreaseBalanceBatch err: %+v", err))
	}

	return nil
}

func (r *customCurrentUserRepository) IncreaseIntegralBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	userIds []uint64,
	step int,
) error {
	var uids []string
	if len(userIds) > 0 {
		for _, uid := range userIds {
			if uid > 0 {
				uids = append(uids, strconv.FormatInt(int64(uid), 10))
			}
		}
	}

	if len(uids) > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		res, err := queries.Raw(fmt.Sprintf(
			`update %s set %s=%s+%d where %s in (%s)`,
			model.TableNames.UserAccount,
			model.UserAccountColumns.Point,
			model.UserAccountColumns.Point,
			step,
			model.UserAccountColumns.UserID,
			strings.Join(uids, ","),
		)).Exec(db)

		logrus.Info(fmt.Sprintf("IncreaseIntegralBatch res: %+v", res))
		logrus.Info(fmt.Sprintf("IncreaseIntegralBatch err: %+v", err))
	}

	return nil
}

func (r *customCurrentUserRepository) IncreaseGrowthBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	userIds []uint64,
	step int,
) error {
	var uids []string
	if len(userIds) > 0 {
		for _, uid := range userIds {
			if uid > 0 {
				uids = append(uids, strconv.FormatInt(int64(uid), 10))
			}
		}
	}

	if len(uids) > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		res, err := queries.Raw(fmt.Sprintf(
			`update %s set %s=%s+%d where %s in (%s)`,
			model.TableNames.UserAccount,
			model.UserAccountColumns.HistoryPoint,
			model.UserAccountColumns.HistoryPoint,
			step,
			model.UserAccountColumns.UserID,
			strings.Join(uids, ","),
		)).Exec(db)

		logrus.Info(fmt.Sprintf("IncreaseGrowthBatch res: %+v", res))
		logrus.Info(fmt.Sprintf("IncreaseGrowthBatch err: %+v", err))
	}

	return nil
}

func (r *customCurrentUserRepository) UpdateMetum(
	ctx context.Context,
	tx boil.ContextExecutor,
	userMetum *model.UserMetum,
) error {
	if userMetum.UserID > 0 && len(userMetum.MetaKey) > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		var mods []qm.QueryMod
		mods = append(mods, model.UserMetumWhere.UserID.EQ(userMetum.UserID))
		mods = append(mods, model.UserMetumWhere.MetaKey.EQ(userMetum.MetaKey))
		list, err := model.UserMeta(mods...).All(ctx, db)
		if err != nil {
			logrus.Info(fmt.Sprintf("UpdateMetum list err: %+v", err))
			if err == sql.ErrNoRows {
				return userMetum.Insert(ctx, db, boil.Infer())
			}

			return err
		}

		if len(list) == 0 {
			return userMetum.Insert(ctx, db, boil.Infer())
		}

		_, err = model.UserMeta(mods...).UpdateAll(ctx, db, model.M{
			model.UserMetumColumns.MetaValue: userMetum.MetaValue,
		})
		if err != nil {
			logrus.Info(fmt.Sprintf("UpdateMetum err: %+v", err))
			return err
		}
	}

	return nil
}

func (r *customCurrentUserRepository) UpdateMeta(
	ctx context.Context,
	tx boil.ContextExecutor,
	meta []*model.UserMetum,
	delMetaIds []uint64,
) error {
	var db boil.ContextExecutor
	if tx != nil {
		db = tx
	} else {
		db = r.mysqlConn
	}

	if len(meta) > 0 {
		for _, metum := range meta {
			if metum.MetaID > 0 {
				_, err := metum.Update(ctx, db, boil.Whitelist(
					model.UserMetumColumns.MetaValue,
				))
				if err != nil {
					return err
				}
			} else {
				err := metum.Insert(ctx, db, boil.Infer())
				if err != nil {
					return err
				}
			}
		}
	}

	if len(delMetaIds) > 0 {
		var mods []qm.QueryMod
		mods = append(mods, model.UserMetumWhere.MetaID.IN(delMetaIds))
		_, err := model.UserMeta(mods...).DeleteAll(ctx, db)
		if err != nil {
			return err
		}
	}

	return nil
}

func (r *customCurrentUserRepository) IncreaseMeta(
	ctx context.Context,
	tx boil.ContextExecutor,
	userId uint64,
	metaKey string,
	step int,
) error {
	if userId == 0 || len(metaKey) == 0 {
		return nil
	}

	var db boil.ContextExecutor
	if tx != nil {
		db = tx
	} else {
		db = r.mysqlConn
	}

	var mods []qm.QueryMod
	mods = append(mods, model.UserMetumWhere.UserID.EQ(userId))
	mods = append(mods, model.UserMetumWhere.MetaKey.EQ(metaKey))
	list, err := model.UserMeta(mods...).All(ctx, db)
	if err != nil {
		return err
	}

	if len(list) == 0 {
		userMetum := &model.UserMetum{
			UserID:    userId,
			MetaKey:   metaKey,
			MetaValue: null.StringFrom(strconv.FormatInt(int64(step), 10)),
		}

		return userMetum.Insert(ctx, db, boil.Infer())
	}

	res, err := queries.Raw(fmt.Sprintf(
		`update %s set %s=%s+%d where %s="%s" and %s="%d"`,
		model.TableNames.UserMeta,
		model.UserMetumColumns.MetaValue,
		model.UserMetumColumns.MetaValue,
		step,
		model.UserMetumColumns.MetaKey,
		metaKey,
		model.UserMetumColumns.UserID,
		userId,
	)).Exec(db)

	logrus.Info(fmt.Sprintf("CurrentUser IncreaseMeta res: %+v", res))
	logrus.Info(fmt.Sprintf("CurrentUser IncreaseMeta err: %+v", err))

	return nil
}

func (r *customCurrentUserRepository) InsertTransactionLog(
	ctx context.Context,
	tx boil.ContextExecutor,
	log *model.UserTransactionLog,
) error {
	if log.UserID > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		return log.Insert(ctx, db, boil.Infer())
	}

	return nil
}

func (r *customCurrentUserRepository) GetTransactionLogList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserTransactionLog, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserTransactionLogColumns.UserTransactionLogID+" DESC"))
					mods = append(mods, model.UserTransactionLogWhere.UserTransactionLogID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserTransactionLogColumns.UserTransactionLogID+" ASC"))
					mods = append(mods, model.UserTransactionLogWhere.UserTransactionLogID.GT(val))
					previousCount = 1
				}
			}
		case "orderBy":
			if withCount != 3 && withCount != 4 {
				if val, ok := v.(string); ok && val != "" {
					mods = append(mods, qm.OrderBy(val))
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && val != "" {
					selectCol = val
				}
			}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserTransactionLogColumns.UserTransactionLogID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.UserTransactionLogID, opMap)...)
			case model.UserTransactionLogColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.UserID, opMap)...)
			case model.UserTransactionLogColumns.AssetType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.AssetType, opMap)...)
			case model.UserTransactionLogColumns.ChangeType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.ChangeType, opMap)...)
			case model.UserTransactionLogColumns.ChangeAmount:
				mods = append(mods, modelx.GetStringMods(model.UserTransactionLogColumns.ChangeAmount, opMap)...)
			case model.UserTransactionLogColumns.SourceType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.SourceType, opMap)...)
			case model.UserTransactionLogColumns.SourceID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.SourceID, opMap)...)
			case model.UserTransactionLogColumns.Status:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.Status, opMap)...)
			}
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserTransactionLogs(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}

		if pageSize > 0 {
			if page > 1 {
				mods = append(mods, qm.Offset(pageSize*(page-1)))
			}
			mods = append(mods, qm.Limit(pageSize))
		}
	} else {
		if pageSize > 0 {
			if page > 1 {
				mods = append(mods, qm.Offset(pageSize*(page-1)))
			}
			mods = append(mods, qm.Limit(pageSize))
		}
	}

	var columns []string
	if selectCol != "" {
		if selectCol != "," {
			columns = strings.Split(selectCol, ",")
		} else {
			columns = append(columns, model.UserTransactionLogColumns.UserTransactionLogID)
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserTransactionLogs(mods...).All(ctx, r.mysqlConn)
	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) UpdateTransactionLogBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	cols model.M,
	filter map[string]map[string][]any,
) (rowsAff int64, err error) {
	var mods []qm.QueryMod
	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserTransactionLogColumns.UserTransactionLogID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.UserTransactionLogID, opMap)...)
			case model.UserTransactionLogColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.UserID, opMap)...)
			case model.UserTransactionLogColumns.AssetType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.AssetType, opMap)...)
			case model.UserTransactionLogColumns.ChangeType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.ChangeType, opMap)...)
			case model.UserTransactionLogColumns.ChangeAmount:
				mods = append(mods, modelx.GetStringMods(model.UserTransactionLogColumns.ChangeAmount, opMap)...)
			case model.UserTransactionLogColumns.OldAmount:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.OldAmount, opMap)...)
			case model.UserTransactionLogColumns.SourceType:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.SourceType, opMap)...)
			case model.UserTransactionLogColumns.SourceID:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.SourceID, opMap)...)
			case model.UserTransactionLogColumns.Status:
				mods = append(mods, modelx.GetIntMods(model.UserTransactionLogColumns.Status, opMap)...)
			}
		}
	}

	if len(mods) == 0 {
		return
	}

	var db boil.ContextExecutor
	if tx != nil {
		db = tx
	} else {
		db = r.mysqlConn
	}

	return model.UserTransactionLogs(mods...).UpdateAll(ctx, db, cols)
}

func (r *customCurrentUserRepository) InsertTaskLog(
	ctx context.Context,
	tx boil.ContextExecutor,
	log *model.UserTaskLog,
) error {
	if log.UserID > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		return log.Insert(ctx, db, boil.Infer())
	}

	return nil
}

func (r *customCurrentUserRepository) InsertIntegralTransactionLog(
	ctx context.Context,
	tx boil.ContextExecutor,
	log *model.UserIntegralTransactionLog,
) error {
	if log.UserID > 0 {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = r.mysqlConn
		}

		return log.Insert(ctx, db, boil.Infer())
	}

	return nil
}

func (r *customCurrentUserRepository) GetIntegralTransactionLog(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserIntegralTransactionLog, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "orderBy":
			if val, ok := v.(string); ok && len(val) > 0 {
				mods = append(mods, qm.OrderBy(val))
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserIntegralTransactionLogColumns.ID+" DESC"))
					mods = append(mods, model.UserIntegralTransactionLogWhere.ID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserIntegralTransactionLogColumns.ID+" ASC"))
					mods = append(mods, model.UserIntegralTransactionLogWhere.ID.GT(val))
					previousCount = 1
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && len(val) > 0 {
					selectCol = val
				}
			}
		}
	}

	for key, opMap := range filter {
		switch key {
		case model.UserIntegralTransactionLogColumns.ID:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.ID, opMap)...)
		case model.UserIntegralTransactionLogColumns.UserID:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.UserID, opMap)...)
		case model.UserIntegralTransactionLogColumns.ProductID:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.ProductID, opMap)...)
		case model.UserIntegralTransactionLogColumns.ProductName:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.ProductName, opMap)...)
		case model.UserIntegralTransactionLogColumns.ProductCode:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.ProductCode, opMap)...)
		case model.UserIntegralTransactionLogColumns.SkuID:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.SkuID, opMap)...)
		case model.UserIntegralTransactionLogColumns.SkuCode:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.SkuCode, opMap)...)
		case model.UserIntegralTransactionLogColumns.Sku:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.Sku, opMap)...)
		case model.UserIntegralTransactionLogColumns.URL:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.URL, opMap)...)
		case model.UserIntegralTransactionLogColumns.OrderID:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.OrderID, opMap)...)
		case model.UserIntegralTransactionLogColumns.OrderSN:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.OrderSN, opMap)...)
		case model.UserIntegralTransactionLogColumns.Points:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.Points, opMap)...)
		case model.UserIntegralTransactionLogColumns.Amount:
			mods = append(mods, modelx.GetStringMods(model.UserIntegralTransactionLogColumns.Amount, opMap)...)
		case model.UserIntegralTransactionLogColumns.Status:
			mods = append(mods, modelx.GetIntMods(model.UserIntegralTransactionLogColumns.Status, opMap)...)
		case model.UserIntegralTransactionLogColumns.CreatedAt:
			mods = append(mods, modelx.GetTimeMods(model.UserIntegralTransactionLogColumns.CreatedAt, opMap)...)
		case model.UserIntegralTransactionLogColumns.UpdatedAt:
			mods = append(mods, modelx.GetTimeMods(model.UserIntegralTransactionLogColumns.UpdatedAt, opMap)...)
		}
	}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserIntegralTransactionLogs(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}
	}

	if pageSize > 0 && (withCount == -1 || withCount == 1) {
		if page > 1 {
			mods = append(mods, qm.Offset(pageSize*(page-1)))
		}
		mods = append(mods, qm.Limit(pageSize))
	}

	var columns []string
	if len(selectCol) > 0 {
		if selectCol == "," {
			columns = append(columns, model.UserIntegralTransactionLogColumns.ID)
		} else {
			columns = strings.Split(selectCol, ",")
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserIntegralTransactionLogs(mods...).All(ctx, r.mysqlConn)
	if err != nil {
		return
	}

	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) GetTaskLogList(
	ctx context.Context,
	cols model.M,
	withCount int,
	filter map[string]map[string][]any,
) (list []*model.UserTaskLog, count int64, err error) {
	var page int
	var pageSize int
	var limit int
	var selectCol string
	var mods []qm.QueryMod
	var nextCount int64
	var previousCount int64
	//var statistic bool
	for k, v := range cols {
		switch k {
		case "page":
			if val, ok := v.(uint64); ok && val > 1 {
				page = int(val)
			}
		case "pageSize":
			if val, ok := v.(uint64); ok && val > 0 {
				pageSize = int(val)
			}
		case "limit":
			if val, ok := v.(uint32); ok && val > 0 {
				limit = int(val)
			}
		case "offset":
			if withCount == 2 {
				if val, ok := v.(uint32); ok && val > 0 {
					mods = append(mods, qm.Offset(int(val)))
					previousCount = 1
				}
			}
		case "preMinId":
			if withCount == 3 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserTaskLogColumns.ID+" DESC"))
					mods = append(mods, model.UserTaskLogWhere.ID.LT(val))
					previousCount = 1
				}
			}
		case "preMaxId":
			if withCount == 4 {
				if val, ok := v.(uint64); ok && val > 0 {
					mods = append(mods, qm.OrderBy(model.UserTaskLogColumns.ID+" ASC"))
					mods = append(mods, model.UserTaskLogWhere.ID.GT(val))
					previousCount = 1
				}
			}
		case "orderBy":
			if withCount != 3 && withCount != 4 {
				if val, ok := v.(string); ok && val != "" {
					mods = append(mods, qm.OrderBy(val))
				}
			}
		case "select":
			if withCount != 5 {
				if val, ok := v.(string); ok && val != "" {
					selectCol = val
				}
			}
			//case "statistic":
			//	if val, ok := v.(string); ok && val == "1" {
			//		statistic = true
			//	}
		}
	}

	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserTaskLogColumns.ID:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.ID, opMap)...)
			case model.UserTaskLogColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.UserID, opMap)...)
			case model.UserTaskLogColumns.TaskID:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.TaskID, opMap)...)
			case model.UserTaskLogColumns.TaskName:
				mods = append(mods, modelx.GetStringMods(model.UserTaskLogColumns.TaskName, opMap)...)
			case model.UserTaskLogColumns.TaskSlug:
				mods = append(mods, modelx.GetStringMods(model.UserTaskLogColumns.TaskSlug, opMap)...)
			case model.UserTaskLogColumns.Gems:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Gems, opMap)...)
			case model.UserTaskLogColumns.Growth:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Growth, opMap)...)
			case model.UserTaskLogColumns.Integrals:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Integrals, opMap)...)
			case model.UserTaskLogColumns.Status:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Status, opMap)...)
			case model.UserTaskLogColumns.CreatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserTaskLogColumns.CreatedAt, opMap)...)
			case model.UserTaskLogColumns.UpdatedAt:
				mods = append(mods, modelx.GetTimeMods(model.UserTaskLogColumns.UpdatedAt, opMap)...)
			}
		}
	}

	//if statistic {
	//	mods = append(mods, qm.Select(fmt.Sprintf(
	//		"%s, count(%s) as %s",
	//		model.UserTaskLogColumns.TaskSlug,
	//		model.UserTaskLogColumns.TaskSlug,
	//		model.UserTaskLogColumns.Growth,
	//	)))
	//	mods = append(mods, qm.GroupBy(model.UserTaskLogColumns.TaskSlug))
	//	preList, preErr := model.UserTaskLogs(mods...).All(ctx, r.mysqlConn)
	//	if preErr != nil {
	//		err = preErr
	//		return
	//	}
	//
	//	return preList, 0, nil
	//}

	if withCount >= 2 {
		if limit > 0 {
			mods = append(mods, qm.Limit(limit+1))
		}
	} else if withCount >= 0 {
		count, err = model.UserTaskLogs(mods...).Count(ctx, r.mysqlConn)
		if err != nil {
			return
		}

		if withCount == 0 {
			return
		}

		if pageSize > 0 {
			if page > 1 {
				mods = append(mods, qm.Offset(pageSize*(page-1)))
			}
			mods = append(mods, qm.Limit(pageSize))
		}
	} else {
		if pageSize > 0 {
			if page > 1 {
				mods = append(mods, qm.Offset(pageSize*(page-1)))
			}
			mods = append(mods, qm.Limit(pageSize))
		}
	}

	var columns []string
	if selectCol != "" {
		if selectCol != "," {
			columns = strings.Split(selectCol, ",")
		} else {
			columns = append(columns, model.UserTaskLogColumns.ID)
		}
	}
	if len(columns) > 0 {
		mods = append(mods, qm.Select(columns...))
	}

	list, err = model.UserTaskLogs(mods...).All(ctx, r.mysqlConn)
	if withCount >= 2 {
		if limit > 0 && len(list) > limit {
			nextCount = 1
			list = list[:limit]
		}
		count = previousCount + nextCount*2
	}

	return
}

func (r *customCurrentUserRepository) UpdateTaskLogBatch(
	ctx context.Context,
	tx boil.ContextExecutor,
	cols model.M,
	filter map[string]map[string][]any,
) (rowsAff int64, err error) {
	var mods []qm.QueryMod
	if filter != nil {
		for key, opMap := range filter {
			switch key {
			case model.UserTaskLogColumns.ID:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.ID, opMap)...)
			case model.UserTaskLogColumns.UserID:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.UserID, opMap)...)
			case model.UserTaskLogColumns.TaskName:
				mods = append(mods, modelx.GetStringMods(model.UserTaskLogColumns.TaskName, opMap)...)
			case model.UserTaskLogColumns.TaskSlug:
				mods = append(mods, modelx.GetStringMods(model.UserTaskLogColumns.TaskSlug, opMap)...)
			case model.UserTaskLogColumns.Growth:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Growth, opMap)...)
			case model.UserTaskLogColumns.Integrals:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Integrals, opMap)...)
			case model.UserTaskLogColumns.Status:
				mods = append(mods, modelx.GetIntMods(model.UserTaskLogColumns.Status, opMap)...)
			}
		}
	}

	if len(mods) == 0 {
		return
	}

	var db boil.ContextExecutor
	if tx != nil {
		db = tx
	} else {
		db = r.mysqlConn
	}

	return model.UserTaskLogs(mods...).UpdateAll(ctx, db, cols)
}

func (r *customCurrentUserRepository) UpdateIntegralTransactionLog(
	ctx context.Context,
	tx boil.ContextExecutor,
	data *model.UserIntegralTransactionLog,
) error {
	err := r.ExecCtx(ctx, func(ctx context.Context, conn *sql.DB) error {
		var db boil.ContextExecutor
		if tx != nil {
			db = tx
		} else {
			db = conn
		}

		if data != nil {
			rowsAff, err := data.Update(ctx, db, boil.Blacklist(
				model.UserIntegralTransactionLogColumns.ID,
			))
			if err != nil {
				return err
			}

			if rowsAff == 0 {
				return model.ErrNotUpdated
			}
		}

		return nil
		//todo: 待检查
	})

	return err
}

func (r *customCurrentUserRepository) FindOneNoCacheIntegralTransactionLog(
	ctx context.Context,
	conn boil.ContextExecutor,
	id uint64,
) (*model.UserIntegralTransactionLog, error) {
	var db boil.ContextExecutor = r.mysqlConn
	if conn != nil {
		db = conn
	}
	data, err := model.FindUserIntegralTransactionLog(ctx, db, id)
	switch err {
	case nil:
		return data, nil
	case sql.ErrNoRows:
		return nil, model.ErrNotFound
	default:
		return nil, err
	}
}
